package com.iwop.moto.controller.web;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.iwop.moto.comm.Comm;
import com.iwop.moto.comm.ErrCode;
import com.iwop.moto.controller.BaseController;
import com.iwop.moto.model.*;
import com.iwop.moto.service.*;
import com.iwop.moto.utils.PushNoticeUtil;
import com.iwop.moto.utils.alipay.AliPayComm;
import com.iwop.moto.utils.alipay.AliPayUtil;
import com.iwop.moto.utils.http.SessionUtils;
import com.iwop.moto.utils.stringUtil.*;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @功能: 支付宝支付
 * @日期: liuwb by 2016-10-31 19:16:38 create
 */
@Controller
public class AliPayController extends BaseController {
    Logger logger = Logger.getLogger(AliPayController.class);

    @Autowired
    private MPaymentService mPaymentService;

    @Autowired
    FOrderServiceService fOrderServiceService;

    @Autowired
    UserService userService;

    @Autowired
    private StoreService storeService;

    @Autowired
    private MCouponService mCouponService;

    @Autowired
    private MOrderPurchaseService mOrderPurchaseService;

    @Autowired
    private PromotionService promotionService;

    @Autowired
    MBrokerageService mBrokerageService;

    @Autowired
    MGPOrderService mgpOrderService;

    @Autowired
    PayService payService;

    /**
     * @功能: App支付宝支付
     * @日期: liuwb by 2016-11-7 13:02:32 create
     * @参数: user_id 用户Id
     * @参数: order_type 交易类型[Service:服务订单支付][Goods:商品订单支付][Topup:充值]
     * @参数: out_trade_no 订单号(开摩邦) (可填) 如果业务订单号（唯一）存在需填写 不存在则系统自动生成
     * @参数: total_amount 金额( 例如: 0.01)
     * @参数: subject 主题 如:(服务订单支付)
     */
    @RequestMapping(value = "/api/app/ali/pay")
    @ResponseBody
    public ResultModel apiAppAlipay(HttpServletRequest request) throws ParseException {
        SuperRecordModel srmParams = this.getSRModel();
        String brokerage = request.getParameter("brokerage");
        logger.error("brokerage:" + brokerage);
        if (StringUtils.isEmpty(brokerage)) {
            brokerage = "0";
        }
        if (srmParams.get("user_id") == null || srmParams.get("order_type") == null
                || srmParams.get("total_amount") == null) {
            return getErr(ErrCode.ERROR_PARAMETER);
        }
        String total_amount = (String) srmParams.get("total_amount");
        logger.error("total_amount:" + total_amount);
        String out_trade_no = (String) srmParams.get("out_trade_no");
        MPayment mPayment = new MPayment();
        mPayment.setOutTradeNo(out_trade_no);
        boolean countBl = mPaymentService.findByPayTradeNoCount(mPayment);
        if (!countBl) {
            return getErr(ErrCode.ERROR_PAY);
        }
        User userBySid = userService.getUserBySid(srmParams.getString("user_id"));
        //抵用券验证
        String coupon_id = request.getParameter("coupon_id");
        String sid = request.getParameter("sid");
        if (!(StringUtils.isEmpty(coupon_id) || StringUtils.isEmpty(sid))) {
            SuperRecordModel superRecordModel = mCouponService.getUserCouponByCouponIdAndUserId(srmParams);
            if (superRecordModel != null && superRecordModel.isEmpty()) {
                logger.error("用户:【" + srmParams.get("user_id").toString() + "】||【" + srmParams.get("coupon_id").toString() + "】抵用券不存在");
                ErrorLog(null, "/api/alipay/gateway:抵用券不存在或系统错误", JsonUtils.toJsonString(srmParams));
                return getErr(ErrCode.ERROR_PARAMETER);
            }
            if (superRecordModel != null) {
                if (!superRecordModel.containsKey("status_flag")) {
                    return getErr(ErrCode.ERROR_PARAMETER);
                }
                if (superRecordModel.get("status_flag") == null) {
                    return getErr(ErrCode.ERROR_PARAMETER);
                }
                if (!superRecordModel.get("status_flag").equals("1")) {
                    ErrorLog(null, "/api/alipay/gateway:抵用券已使用或者已失效", JsonUtils.toJsonString(srmParams));
                    logger.error(srmParams.get("coupon_id") + ":抵用券已使用或者已失效");
                    return getErr(ErrCode.ERROR_PARAMETER);
                }
            }

        }
        double brokerages = Double.parseDouble(brokerage);
        if (userBySid.getRedPacket() < brokerages) {
            return getErr(ErrCode.ERROR_BROKERAGE);
        }
        String ctype = request.getParameter("ctype");
        String order_type = (String) srmParams.get("order_type");
        if (order_type.equals("Service")) {
            if (!out_trade_no.contains("Ho")) {
                if (StringUtils.isEmpty(ctype)) {
                    ctype = "user";
                    SuperRecordModel storeOrderBySid = fOrderServiceService.getStoreOrderByOrderNo(out_trade_no);
                    if (storeOrderBySid == null || storeOrderBySid.size() == 0) {
                        return getErr(ErrCode.ERROR_SYSTEM);
                    }
                    out_trade_no = SequenceUtil.Serial("So");
                    storeOrderBySid.put("pay_order_no", out_trade_no);
                    fOrderServiceService.updateStoreOrder(storeOrderBySid);
                } else {
                    MOrderPurchase oneById = mOrderPurchaseService.findOneById(out_trade_no);
                    if (oneById == null) {
                        return getErr(ErrCode.ERROR_PARAMETER);
                    }
                    out_trade_no = SequenceUtil.Serial("Co");
                    oneById.setPayOrderNo(out_trade_no);
                    mOrderPurchaseService.updateOrderPurchase(oneById);
                }
            } else {
                MGPOrder oneBySid = mgpOrderService.findOneBySid(out_trade_no);
                if (oneBySid == null) {
                    return getErr(ErrCode.ERROR_SYSTEM);
                }
                out_trade_no = SequenceUtil.Serial("Ho");
                oneBySid.setPayTradeNo(out_trade_no);
                mgpOrderService.updateMGPOrder(oneBySid);
            }
        }
        Map alipayResult = new HashMap();
        try {
            Map<String, Object> alipayParams = new HashMap<>();
            if (srmParams.containsKey("coupon_id")) {
                if (StringUtils.isEmpty(srmParams.getString("coupon_id"))) {
                    srmParams.remove("coupon_id");
                }
            }

            srmParams.put("ctype", ctype);
            srmParams.put("brokerage", brokerage);
            alipayParams.put("body", srmParams);
            String subject = srmParams.getString("subject");
            if (StringUtils.isEmpty(subject)) {
                subject = "";
            }
            alipayParams.put("subject", subject);
            if (StringUtils.isEmpty(out_trade_no)) {
                out_trade_no = SequenceUtil.Serial("SEQ-");
            }
            alipayParams.put("out_trade_no", out_trade_no);
            alipayParams.put("timeout_express", "30m");

            double afterMoney = 0;
            if (!StringUtils.isEmpty(total_amount)) {
                afterMoney = Double.parseDouble(total_amount);
            }
            if (afterMoney == 0) {
                afterMoney = 0.01;
            }
            alipayParams.put("total_amount", afterMoney);
            alipayParams.put("product_code", Comm.QUICK_MSECURITY_PAY);
            /** 根据参数生成请求体 **/
            alipayResult = AliPayUtil.buildOrderParamMap(JsonUtils.toJsonString(alipayParams));
            String orderParams = AliPayUtil.buildOrderParam(alipayResult);
            String sign = AliPayUtil.getSign(alipayResult, AliPayComm.PRIVATE_KEY);
            alipayResult.put("sign", sign);
            alipayResult.put("app_params", orderParams + "&" + sign);
        } catch (Exception e) {
            e.printStackTrace();
            ErrorLog(e, "/api/app/ali/pay", JsonUtils.toJsonString(alipayResult));
            return getErr(ErrCode.ERROR_SYSTEM);
        }
        return getSucceed(alipayResult);
    }


    /**
     *
     * */
    @RequestMapping(value = "/api/alipay/h5/pay")
    @ResponseBody
    public void apiH5AliPay(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, IOException {
        String out_trade_no = request.getParameter("out_trade_no");
        String money = request.getParameter("money");
        String store_id = request.getParameter("store_id");
        double payMoney = Double.parseDouble(money);
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", AliPayComm.APP_ID, AliPayComm.PRIVATE_KEY, "json", "utf-8", AliPayComm.ALIPAY_PUBLIC_KEY);
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request

        SuperRecordModel storeBySid = storeService.getStoreBySid(store_id);

        // String param="?image="+storeBySid.getString("storepath")+"&name="+storeBySid.getString("storename")+"&money="+money;
        alipayRequest.setReturnUrl(Comm.ALIPAYBACKURL);
        String notifyUrl = Comm.HTTP_URL + "/api/alipay/notice/gateway";
        alipayRequest.setNotifyUrl(notifyUrl);//在公共参数中设置回跳和通知地址
        Map alipayResult = new HashMap();
        alipayResult.put("out_trade_no", out_trade_no);
        alipayResult.put("total_amount", payMoney);
        // alipayResult.put("store_id",store_id);
        alipayResult.put("subject", "开摩邦网-扫码支付");
        alipayResult.put("seller_id", "2088521119856530");
        alipayResult.put("product_code", "QUICK_WAP_PAY");
        //alipayResult.put("body", JSON.toJSONString(alipayResult));
        alipayRequest.setBizContent(JsonUtils.toJsonString(alipayResult));//填充业务参数
        String form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(form);//直接将完整的表单html输出到页面
        response.getWriter().flush();
    }

    @RequestMapping(value = "/api/alipay/notice/gateway")
    @ResponseBody
    public String apiAliPayNoticeGateway(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
        System.out.println("===============H5回调=========================");
        Map<String, String> params = null;
        try {
            params = getRequestParams(request);
            return payService.addAliH5PayBack(params);
        } catch (Exception e) {
            e.printStackTrace();
            return "SUCCESS";
        }
    }

    /**
     * @功能: 支付包回调函数 / 应用网关
     * @日期: liuwb by 2016-11-3 16:45:02 Create
     */
    @RequestMapping(value = "/api/alipay/gateway")
    @ResponseBody
    public String apiAliPayGateway(HttpServletRequest request, HttpServletResponse response) {
        String responseMsg = "failure"; //支付宝响应消息
        Map<String, String> params = getRequestParams(request); //1. 解析请求参数
        try {
            //验证签名
            boolean resultBl = AlipaySignature.rsaCheckV1(params, AliPayComm.ALIPAY_PUBLIC_KEY,
                    AliPayComm.SIGN_CHARSET);
            Map body = JsonUtils.toMap(params.get("body"));
            String s = payService.addAliBack(params, resultBl, body);
            return s;
        } catch (Exception e) {
            e.printStackTrace();
            ErrorLog(e, "/api/alipay/gateway:系统异常", JsonUtils.toJsonString(params));
            return responseMsg;
        }
    }

    /**
     * 添加佣金
     */
    public void addBrokerage(String user_id, String order_id, double moneys) {
        if (moneys >= 5) {
            String keyName = user_id + "_new";
            String valueFromSession = (String) SessionUtils.getValueFromSession(keyName);
            if (!StringUtils.isEmpty(valueFromSession)) {
                if (valueFromSession.equals("new")) {
                    String hostUserInfo = promotionService.findHostUserById(user_id);
                    int count = promotionService.countFromUserByHostId(hostUserInfo);
                    double money = getBrokerage(count);
                    if (!StringUtils.isEmpty(hostUserInfo)) {
                        User userBySid = userService.getUserBySid(hostUserInfo);
                        if (userBySid != null) {
                            MBrokerage mBrokerage = new MBrokerage();
                            mBrokerage.setSid(ObjectId.UUID());
                            mBrokerage.setSellerUserId(userBySid.getSid());
                            mBrokerage.setBuyerUserId(user_id);
                            mBrokerage.setOriginalTmoney(userBySid.getRedPacket());
                            double modifyTmoney = userBySid.getRedPacket() + money;
                            mBrokerage.setModifyTmoney(modifyTmoney);
                            mBrokerage.setPayMoney(money);
                            mBrokerage.setPayStatus("1");
                            mBrokerage.setPayType("ALIPAY");
                            mBrokerage.setPayTime(new Date());
                            mBrokerage.setOutTradeNo(order_id);
                            mBrokerageService.insert(mBrokerage);
                            userBySid.setRedPacket(modifyTmoney);
                            userService.updateRedPacketBySid(userBySid);
                            SessionUtils.setKeyValueString(keyName, "old");
                            User userBySid1 = userService.getUserBySid(user_id);
                            userBySid1.setNewUser("old");
                            userService.updateRedPacketBySid(userBySid1);
                        }
                    }
                }
            }
        }
    }

    /**
     * 判断是推送付款订单，采购订单
     */
    private User judgeOrderType(Map attach) {
        User storeUser = new User();
        String orderType = (String) attach.get("ctype");
        String out_trade_no = (String) attach.get("out_trade_no");
        if (out_trade_no.contains("Ho")) {
            MGPOrder mgpOrder = mgpOrderService.findOneBySid(out_trade_no);
            SuperRecordModel store = storeService.getStoreBySid(mgpOrder.getStoreId());
            storeUser = userService.getUserBySid(store.get("user_id").toString());
        } else {
            if (orderType.equals("user")) {
                SuperRecordModel service = new SuperRecordModel();
                service = fOrderServiceService.getStoreOrderByOrderNo(out_trade_no);
                service.put("pushstatus", "1");//支付成功
                fOrderServiceService.updateStoreOrderStatus(service);
                SuperRecordModel store = storeService.getStoreBySid(service.get("store_id").toString());
                storeUser = userService.getUserBySid(store.get("user_id").toString());
            } else {
                MOrderPurchase mOrderPurchase = mOrderPurchaseService.findOneByPayOrderNo(out_trade_no);
                mOrderPurchase.setStatus(1);
                mOrderPurchaseService.updateOrderPurchase(mOrderPurchase);
                SuperRecordModel store = storeService.getStoreBySid(mOrderPurchase.getSellerStoreId());
                storeUser = userService.getUserBySid(store.get("user_id").toString());
            }
        }
        return storeUser;
    }

    private double getBrokerage(int people) {
        if (people < 19) {
            return 4;
        } else if (people < 99) {
            return 5;
        } else {
            return 6;
        }
    }

    /**
     * 逻辑更新优惠券
     *
     * @param user_id
     * @param coupon_id
     * @param status_flag       是否使用过（1：未使用，2：已使用）
     * @param superRecordModel1
     */
    @Transactional
    public void updateCouponStatus(SuperRecordModel superRecordModel1) {
        try {
            mCouponService.updateUserCouponStatusBySid(superRecordModel1);
        } catch (Exception e) {
            e.printStackTrace();
            ErrorLog(e, "method:updateCouponStatus系统异常", JsonUtils.toJsonString(superRecordModel1));
        }
    }
}

